/*
 * ESP32 Bluetooth Audio Receiver - Audio Processor Implementation
 *
 * Developed based on ESP-IDF framework using Espressif official interfaces
 * Core audio processing algorithms, hardware adaptation, sound quality optimization are original development
 *
 * Copyright (c) 2025 lianggumei
 *
 * SPDX-License-Identifier: MIT
 */

#include "audio_processor.hpp"

#include "bt_app_core.h"

const char* AudioProcessor::kTag = "AudioProcessor";

AudioProcessor::AudioProcessor() : volume_(50), i2s_writer_(nullptr) {
  ESP_LOGI(kTag, "Audio processor initialized");
}

AudioProcessor::~AudioProcessor() {
  ESP_LOGI(kTag, "Audio processor destroyed");
}

void AudioProcessor::ProcessAudioData(const uint8_t* data, size_t len, uint8_t volume) {
  if (data == nullptr || len == 0) {
    return;
  }

  volume_ = volume;

  // When volume is 0, discard audio data to achieve mute effect
  if (volume_ == 0) {
    return;
  }
  // Process audio data
  ProcessAudioDataInternal(data, len);
}

void AudioProcessor::SetVolume(uint8_t volume) {
  volume_ = volume;
}

uint8_t AudioProcessor::GetVolume() const {
  return volume_;
}

void AudioProcessor::SetI2SWriter(void (*writer)(const uint8_t*, size_t)) {
  i2s_writer_ = writer;
}

void AudioProcessor::ProcessAudioDataInternal(const uint8_t* data, size_t len) {
  // Process audio data

  // Audio data buffer
  static uint8_t processed_data[4096];
  size_t processed_len = len;

  if (len <= sizeof(processed_data)) {
    // Copy data to processing buffer
    memcpy(processed_data, data, len);

    // Volume control: logic consistent with C version
    if (len >= 4) {  // Ensure sufficient data for processing
      int16_t* audio_data = reinterpret_cast<int16_t*>(processed_data);
      int samples = len / 2;  // 16-bit sample count

      // Volume control: increase volume amplification to make speaker louder
      float volume_factor = static_cast<float>(volume_) / 127.0f;  // 0.0 - 1.0
      volume_factor *= 2.5f;  // Increase volume by 2.5x

      for (int i = 0; i < samples; i += 2) {  // Process stereo
        int16_t left = audio_data[i];
        int16_t right = audio_data[i + 1];

        // Apply volume factor
        left = static_cast<int16_t>(left * volume_factor);
        right = static_cast<int16_t>(right * volume_factor);

        // Range limiting to prevent overflow while maintaining audio dynamics
        if (left > 32000) left = 32000;  // Close to 16-bit maximum
        if (left < -32000) left = -32000;
        if (right > 32000) right = 32000;
        if (right < -32000) right = -32000;

        audio_data[i] = left;
        audio_data[i + 1] = right;
      }
    }

    // Write processed audio data to I2S buffer
    if (i2s_writer_) {
      i2s_writer_(processed_data, processed_len);
    }
  } else {
    // Data too large, write raw data directly
    if (i2s_writer_) {
      i2s_writer_(data, len);
    }
  }
}
